Asteroids v1.0 by Odis
==================================================================
http://ew.xidus.net

Disclaimer
==========
This code was tested on a heavily modified version of SWR 1.0, but is should work on
everyones code anyway. I retain no responsibility if this code does anything to
your code, your game, or the system it's running on.

This code may need to be modified, do to its nature and how its really set up. Anyways, yeah.

Description
===========
This is a very extensive snippet. It allows for asteroids to be created by immortals.
These asteroids will float around in space and will move depending on their speed. Ships can
crash into them and each side will take damage accordingly. Ships in space may shoot down
the asteroids to gain a set ammount of experience. The asteroid will then be extracted from
the system and will be set with a timer. After a time the asteroid will be put back in the
system.

Area's can be assigned to an asteroid to provide a space to land. Also please note that currently if the asteroid
is destroyed with people on the surface people will not die and will probably not be able to relaunch their ship
form the asteroid until it is put back in the system. I will do some more supporting code with this in the next release.
Also please note that it will need to be -YOU- that modifies do_land to get people to be able to land on the asteroids
until version 2.0.

Asteroids are created much like ships and are set/created/reviewed with the following commands:
makeasteroid <filename> <asteroid name>                               - Creates an asteroid with default values
copyasteroid <old asteroid name> <new file name> <new asteroids name> - Creates a new asteroid with all of
                                                                        the values from the old asteroid.
setasteroid <asteroid name> <field> <values>                          - Sets an asteroid's value in a specific 
                                                                        area and saves the asteroid.
showasteroid <asteroid name>                                          - Show's an asteroids stats
resetasteroid <name> <type> <stype> <exp> <save?:y/n>                 - Resets an asteroid using these specific qualities.
Note: if exp is set to -1 it will calculate it for you
ANNOYING CAPITALIZED WARNING: This function is pretty much useless, I forget why I created it :P

There is a lot of room for expansion. For instance, the code has some refernece's to ore's. This will be another snippet
I release. It will be a module for this system. Also, there are numerous flags you could add, and I can think of a few
I will use in my mud and I will add to further distributions.

If you have questions, just e-mail me or visit my forums at: http://ew.xidus.net/modules.php?name=Forums

Various information:
The asteroids.c file is some 1200 lines long. Asteroids.h is 77. With the supporting code I have no clue what
this adds up to. Also, I'm not sure why I'm puting this in here. Just something worth noting I guess.

=================
Conditions of Use
=================
Well, just drop me an e-mail at admin@ew.xidus.net or post on my forums (listed above a few lines) or something.
If you use this let me know! Maybe I'll come check it out, see how its workin for you.

It would be nice to be mentioned in the credits help file, however, this is no requirement seeing how I cannot
make yous tick to it anyways. However, I do believe you should credit people for their work. If someone asks
where you got your asteroids then please just tell them Odis from GW:A wrote it and you can get it from his web site!

But yeah, just have fun with it and let me know how it goes :)

============================
Part 1: Installing the files
============================
(1) Unpack the files asteroids.c and asteroids.h into the src directory.

(2) Update your make file. In the sections with the .o files and .c files add asteroids.o and asteroids.c

(3) Up above that enter this EXACTLY:

#Ore Module Support - Odis
#ORE = 1

This will be used later on. If you never plan to have ore's in your asteroids just put it in like that and leave it.
The ore module snippet (release date unkown) will provide more information. Just note that you will get errors if you
do not have it commented out like above.

(4) Save your Makefile. Do not recompile yet!

(5) Drop the asteroids folder into your main directory (the one that contains area, player, system, src, etc...)

===================================
End of Part 1: Installing the files
===================================

================================================
Part 2: Adding the support code (This is long!)
================================================

(1) mud.h
-----------------------
 Find:
 #define LEVEL_LOG                   LEVEL_LESSER

 Add -ABOVE- that:
 #include "asteroids.h"

 Note: You do not need to add any DECLARE_DO_FUN's because they are in asteroids.h :)
-----------------------
 Find: the space data struct (struct space_data)

 Add anywhere -WITHIN- the structure:

    ASTEROID_DATA * first_asteroid;
    ASTEROID_DATA * last_asteroid;
-----------------------
 Find: the ship data struct (struct ship_data)

 Add anywhere -WITHIN- the structure:

    ASTEROID_DATA *     atarget0;
    ASTEROID_DATA *     atarget1;
    ASTEROID_DATA *     atarget2;
-----------------------
(2) tables.c
-----------------------
 Find:
   if ( !str_cmp( name, "do_makearmor" ))          return do_makearmor;

 Add under:
 if ( !str_cmp( name, "do_makeasteroid" ))          return do_makeasteroid;
-----------------------
 Find:
   if ( !str_cmp( name, "do_reset" ))              return do_reset;

 Add under:
  if ( !str_cmp( name, "do_resetasteroid" ))      return do_resetasteroid;
-----------------------
  Find:
   if ( !str_cmp( name, "do_set_boot_time" ))      return do_set_boot_time;

  Add under:
   if ( !str_cmp( name, "do_setasteroid" ))	return do_setasteroid;
-----------------------
  Find:
        if ( !str_cmp( name, "do_shove" ))              return do_shove;

  Add under:
        if ( !str_cmp( name, "do_showasteroid" ))       return do_showasteroid;
-----------------------
  Find:
        if ( !str_cmp( name, "do_consider" ))           return do_consider;

  Add under:
        if ( !str_cmp( name, "do_copyasteroid" ))       return do_copyasteroid;
-----------------------
 Find:
    if ( skill == do_makeshield )       return "do_makeshield";
 
 Add under:
    if ( skill == do_makeasteroid )     return "do_makeasteroid";
    if ( skill == do_setasteroid )	    return "do_setasteroid";
    if ( skill == do_resetasteroid )    return "do_resetasteroid";
    if ( skill == do_showasteroid )	    return "do_showasteroid";
    if ( skill == do_copyasteroid )	    return "do_copyasteroid";
-----------------------
 (3) db.c
-----------------------
 Find: in function boot_db find the following section
    first_object        = NULL;
    last_object         = NULL;
    first_char          = NULL;
    last_char           = NULL;
    first_area          = NULL;
    last_area           = NULL;
    first_build         = NULL;
    last_area           = NULL;
    first_shop          = NULL;
    last_shop           = NULL;
    first_repair        = NULL;
    last_repair         = NULL;
    first_teleport      = NULL;
    last_teleport       = NULL;
    first_asort         = NULL;
    last_asort          = NULL;
    extracted_obj_queue = NULL;
    extracted_char_queue= NULL;

 Add into the list:
    first_asteroid      = NULL;
    last_asteroid       = NULL;
-----------------------
Find: in the same function
        log_string( "Resetting areas" );
        area_update( );

Add under:
        log_string( "Loading asteroids" );
        load_asteroids( );
-----------------------
 (4) update.c
-----------------------
Find this:
    if ( --pulse_violence <= 0 )
    {
        pulse_violence  = PULSE_VIOLENCE;
        violence_update ( );
    }

Add to it to make it look like this:
    if ( --pulse_violence <= 0 )
    {
        pulse_violence  = PULSE_VIOLENCE;
        violence_update ( );
        update_asteroids ( ); /* this is the line being added */
    }

-----------------------
 (5) act_info.c
-----------------------
 Find (in do_look):
              if (ship->starsystem)
              {
                   MISSILE_DATA *missile;
                   SHIP_DATA *target;

Add ASTEROID_DATA *asteroid; to it to make it look like:
             if (ship->starsystem)
              {
                   ASTEROID_DATA * asteroid;
                   MISSILE_DATA *missile;
                   SHIP_DATA *target;
-----------------------
Under this section:
              if ( ship->starsystem->star1 && str_cmp(ship->starsystem->star1,"") )
                         ch_printf(ch, "%s\n\r" ,
                                ship->starsystem->star1);
                   if ( ship->starsystem->star2 && str_cmp(ship->starsystem->star2,"")  )
                         ch_printf(ch, "%s\n\r" ,
                                ship->starsystem->star2 );
                   if ( ship->starsystem->planet1 && str_cmp(ship->starsystem->planet1,"") )
                         ch_printf(ch, "%s\n\r" ,
                                ship->starsystem->planet1 );
                   if ( ship->starsystem->planet2 && str_cmp(ship->starsystem->planet2,"")  )
                         ch_printf(ch, "%s\n\r" ,
                                ship->starsystem->planet2 );
                   if ( ship->starsystem->planet3 && str_cmp(ship->starsystem->planet3,"")  )
                         ch_printf(ch, "%s\n\r" ,
                                ship->starsystem->planet3 );

Add this:
                   for ( asteroid = ship->starsystem->first_asteroid; asteroid; asteroid = asteroid->next_in_system )
                   {
                        if ( asteroid == ship->starsystem->first_asteroid )
                          ch_printf( ch, "\n\r", 0 );

                        ch_printf( ch, "%s\n\r", asteroid->name );
                   }
-----------------------
 (6) space.c (this is the longest one)
-----------------------
Find the top of void move_ships which looks like:
	void move_ships( )
	{
	   SHIP_DATA *ship;
	   MISSILE_DATA *missile;
	   MISSILE_DATA *m_next;
	   SHIP_DATA *target;
	   float dx, dy, dz, change;
	   char buf[MAX_STRING_LENGTH];
	   CHAR_DATA *ch;
	   bool ch_found = FALSE;

And add ASTEROID_DATA *asteroid; to it so it looks like:
	void move_ships( )
	{
	   SHIP_DATA *ship;
	   ASTEROID_DATA *asteroid;
	   MISSILE_DATA *missile;
	   MISSILE_DATA *m_next;
	   SHIP_DATA *target;
	   float dx, dy, dz, change;
	   char buf[MAX_STRING_LENGTH];
	   CHAR_DATA *ch;
	   bool ch_found = FALSE;
-----------------------
Go down and find:
          for ( target = ship->starsystem->first_ship; target; target = target->next_in_starsystem)
          {
                if ( target != ship &&
                    abs(ship->vx - target->vx) < 1 &&
                    abs(ship->vy - target->vy) < 1 &&
                    abs(ship->vz - target->vz) < 1 )
                {
                    ship->collision = target->maxhull;
                    target->collision = ship->maxhull;
                }
          }

Add this under it:
          for ( asteroid = ship->starsystem->first_asteroid; asteroid; asteroid = asteroid->next_in_system)
          {
                if (abs(ship->vx - asteroid->x) < 1 &&
                    abs(ship->vy - asteroid->y) < 1 &&
                    abs(ship->vz - asteroid->z) < 1 )
                {
                    ship->collision = asteroid->maxhp;
                    asteroid->collision = ship->maxhull;
                }
          }
-----------------------
Find void fread_starsystem( SPACE_DATA *starsystem, FILE *fp ) and look for:
 if ( !str_cmp( word, "End" ) )
 {
  /* bunch of stuff here */
 }


Add this somewhere near the last curly bracket:
                starsystem->first_asteroid      = NULL; /* These two for safety :) */
                starsystem->last_asteroid       = NULL;
-----------------------
Find void do_makestarsystem and look for:
                  starsystem->star1            = STRALLOC( "" );
                  starsystem->star2            = STRALLOC( "" );

Add -UNDER- that:
                  starsystem->first_asteroid    = NULL;
                  starsystem->last_asteroid     = NULL;
-----------------------

This may be the longest. Do_target and do_fire::sigh:: Due to the complexity of which instructions must be done
I can only give you an unmodified versions of do_target and do_fire that have the ability to target asteroids
and fire your lasers. It is upon you to expand what you can fire at them (eg, missiles, torpedo's, that type of thing)
Perhaps in version 2.0 I will have a fully modified one for you.

/*
 * I believe this is stock do_target with asteroid modifications. Sorry if its sloppy to read, .txt files suck!
 *                                      ~Odis
 */
void do_target(CHAR_DATA *ch, char *argument )
{
    char arg[MAX_INPUT_LENGTH];
    int chance;
    SHIP_DATA *ship;
    SHIP_DATA *target;
    ASTEROID_DATA *asteroid;
    char buf[MAX_STRING_LENGTH];
    
    strcpy( arg, argument );    
    
    switch( ch->substate )
    { 
    	default:
    	        if (  (ship = ship_from_turret(ch->in_room->vnum))  == NULL )
    	        {
    	            send_to_char("&RYou must be in the gunners seat or turret of a ship to do that!\n\r",ch);
    	            return;
    	        }
                
                if ( ship->class > SHIP_PLATFORM )
    	        {
    	            send_to_char("&RThis isn't a spacecraft!\n\r",ch);
    	            return;
    	        }
    	        
                if (ship->shipstate == SHIP_HYPERSPACE)
                {
                  send_to_char("&RYou can only do that in realspace!\n\r",ch);
                  return;   
                }              

    	        if (!ship->starsystem )
    	        {
    	            send_to_char("&RYou can't do that until you've finished launching!\n\r",ch);
    	            return;
    	        }
              
              if ( autofly(ship) )
    	        {
    	            send_to_char("&RYou'll have to turn off the ships autopilot first....\n\r",ch);
    	            return;
    	        }
    	            
              if (arg[0] == '\0')
    	        {
    	            send_to_char("&RYou need to specify a target!\n\r",ch);
    	            return;
    	        }
                
                if ( !str_cmp( arg, "none") )
    	        {
    	            send_to_char("&GTarget set to none.\n\r",ch);
    	            if ( ch->in_room->vnum == ship->gunseat )
			{
			   ship->atarget0 = NULL;
    	                   ship->target0 = NULL;
			}
    	            if ( ch->in_room->vnum == ship->turret1 )
			{
			   ship->atarget1 = NULL;
    	                   ship->target1 = NULL;
			}
    	            if ( ch->in_room->vnum == ship->turret2 )
			{
			   ship->atarget2 = NULL;
    	                   ship->target2 = NULL;
			}
    	            return;
    	        }
                
                target = get_ship_here( arg, ship->starsystem );
		    asteroid = get_asteroid_here( arg, ship->starsystem );

                if (  target == NULL && asteroid == NULL )
                {
                    send_to_char("&RThats not here!\n\r",ch);
                    return;
                }
                
                if (  target != NULL && target == ship )
                {
                    send_to_char("&RYou can't target your own ship!\n\r",ch);
                    return;
                }
                
                if ( target != NULL && !str_cmp(target->owner, ship->owner) && str_cmp( target->owner , "" ) )
                {
                    send_to_char("&RThat ship has the same owner... try targetting an enemy ship instead!\n\r",ch);
                    return;
                }

                if ( target != NULL && (abs(ship->vx-target->vx) > 5000 ||
                     abs(ship->vy-target->vy) > 5000 ||
                     abs(ship->vz-target->vz) > 5000) )
                {
                    send_to_char("&RThat ship is too far away to target.\n\r",ch);
                    return;
                }
                
                chance = IS_NPC(ch) ? ch->top_level
	                 : (int)  (ch->pcdata->learned[gsn_weaponsystems]) ;
                if ( number_percent( ) < chance )
    		{
    		   send_to_char( "&GTracking target.\n\r", ch);
   		   act( AT_PLAIN, "$n makes some adjustments on the targeting computer.", ch,		        NULL, argument , TO_ROOM );
    		   add_timer ( ch , TIMER_DO_FUN , 1 , do_target , 1 );
    		   ch->dest_buf = str_dup(arg);
    		   return;
	        }
	        send_to_char("&RYou fail to work the controls properly.\n\r",ch);
	        learn_from_failure( ch, gsn_weaponsystems );
    	   	return;	
    	
    	case 1:
    		if ( !ch->dest_buf )
    		   return;
    		strcpy(arg, ch->dest_buf);
    		DISPOSE( ch->dest_buf);
    		break;
    		
    	case SUB_TIMER_DO_ABORT:
    		DISPOSE( ch->dest_buf );
    		ch->substate = SUB_NONE;
    		if ( (ship = ship_from_cockpit(ch->in_room->vnum)) == NULL )
    		      return;    		                                   
    	        send_to_char("&RYour concentration is broken. You fail to lock onto your target.\n\r", ch);
    		return;
    }
    
    ch->substate = SUB_NONE;
    
    if ( (ship = ship_from_turret(ch->in_room->vnum)) == NULL )
    {  
       return;
    }
    
    target = get_ship_here( arg, ship->starsystem );
    asteroid = get_asteroid_here( arg, ship->starsystem );

    if (  (target == NULL || target == ship) && asteroid == NULL)
    {
           send_to_char("&RThe ship has left the starsytem. Targeting aborted.\n\r",ch);
           return;
    }

    if ( asteroid == NULL )
    {
	   send_to_char("&RSorry, that asteroid must have been destroyed.\n\r", ch );
    	   return;
    }
  
    if ( ch->in_room->vnum == ship->gunseat && target != NULL)
       ship->target0 = target;
    
    if ( ch->in_room->vnum == ship->turret1 && target != NULL)
       ship->target1 = target;
             
    if ( ch->in_room->vnum == ship->turret2 && target != NULL)
        ship->target2 = target;      

    if ( ch->in_room->vnum == ship->gunseat && asteroid != NULL)
       ship->atarget0 = asteroid;
    
    if ( ch->in_room->vnum == ship->turret1 && asteroid != NULL)
       ship->atarget1 = asteroid;

    if ( ch->in_room->vnum == ship->turret2 && asteroid != NULL)
        ship->atarget2 = asteroid;      
    
    send_to_char( "&GTarget Locked.\n\r", ch);

    if ( target != NULL )
    {
		sprintf( buf , "You are being targetted by %s." , ship->name);  
		echo_to_cockpit( AT_BLOOD , target , buf );
    }
       	         	         
    learn_from_success( ch, gsn_weaponsystems );
    	
    if ( autofly(target) && target != NULL && !target->target0)
    {
       sprintf( buf , "You are being targetted by %s." , target->name);  
       echo_to_cockpit( AT_BLOOD , ship , buf );
       target->target0 = ship;
    }
}

/*
 * Sorry, but this one is really vague! If you havent made any modifications to the stock do_fire function
 * you could prolly just copy and paste. Please note this is firing support for lasers only...    ~Odis
 */
void do_fire(CHAR_DATA *ch, char *argument )
{
    int chance;
    SHIP_DATA *ship;
    SHIP_DATA *target;
    ASTEROID_DATA *asteroid;
    char buf[MAX_STRING_LENGTH];
    
        if (  (ship = ship_from_turret(ch->in_room->vnum))  == NULL )
        {
            send_to_char("&RYou must be in the gunners chair or turret of a ship to do that!\n\r",ch);
            return;
        }
        
        if ( ship->class > SHIP_PLATFORM )
    	        {
    	            send_to_char("&RThis isn't a spacecraft!\n\r",ch);
    	            return;
    	        }
    	        
        if (ship->shipstate == SHIP_HYPERSPACE)
        {
             send_to_char("&RYou can only do that in realspace!\n\r",ch);
             return;   
        }
    	if (ship->starsystem == NULL)
    	{
    	     send_to_char("&RYou can't do that until after you've finished launching!\n\r",ch);
    	     return;
    	}
    	if ( ship->energy <5 )
        {
             send_to_char("&RTheres not enough energy left to fire!\n\r",ch);
             return;
        }   
  
                if ( autofly(ship) )
    	        {
    	            send_to_char("&RYou'll have to turn off the ships autopilot first.\n\r",ch);
    	            return;
    	        }
    	              
        
        chance = IS_NPC(ch) ? ch->top_level
                 : (int) ( ch->perm_dex*2 + ch->pcdata->learned[gsn_spacecombat]/3
                           + ch->pcdata->learned[gsn_spacecombat2]/3 + ch->pcdata->learned[gsn_spacecombat3]/3 );        
        
    	if ( ch->in_room->vnum == ship->gunseat && !str_prefix( argument , "lasers") )
    	{
    	
    	     if (ship->statet0 == LASER_DAMAGED)
    	     {
    	        send_to_char("&RThe ships main laser is damaged.\n\r",ch);
    	      	return;
    	     } 
             if (ship->statet0 >= ship->lasers )
    	     {
    	     	send_to_char("&RThe lasers are still recharging.\n\r",ch);
    	     	return;
    	     }
    	     if (ship->target0 == NULL && ship->atarget0 == NULL )
    	     {
    	     	send_to_char("&RYou need to choose a target first.\n\r",ch);
    	     	return;
    	     }    	    

    	     target = ship->target0;
	     asteroid = ship->atarget0;

    	     if (ship->target0 != NULL && ship->target0->starsystem != ship->starsystem)
    	     {
    	     	send_to_char("&RYour target seems to have left.\n\r",ch);
    	        ship->target0 = NULL; 
    	     	return;
    	     } 

	     if (ship->atarget0 != NULL && ship->atarget0->starsystem != ship->starsystem)
	     {
		send_to_char("&RYour target seems to have been destroyed..\n\r", ch );
		ship->atarget0 = NULL;
		return;
	     }

             if ( target != NULL && (abs(target->vx - ship->vx) >1000 ||
                  abs(target->vy - ship->vy) >1000 ||
                  abs(target->vz - ship->vz) >1000) )
             {
                send_to_char("&RThat target is out of laser range.\n\r",ch);
    	     	return;
             } 

	     if ( asteroid != NULL && (abs(asteroid->x - ship->vx) > 1000 ||
		  abs(asteroid->y - ship->vy) > 1000 ||
		  abs(asteroid->z - ship->vz) > 1000) )
	     {
		send_to_char("&RThat asteroid is out of range!\n\r", ch );
		return;
  	     }

             if ( target != NULL && ship->class < 2 && !is_facing( ship, target ))
             {
                send_to_char("&RThe main laser can only fire forward. You'll need to turn your ship!\n\r",ch);
    	     	return;
             }      
             ship->statet0++;
	     if ( target != NULL && asteroid == NULL )
	     {
             chance += target->class*25;
             chance -= target->manuever/10;
             chance -= target->currspeed/20;
             chance -= ( abs(target->vx - ship->vx)/70 );
             chance -= ( abs(target->vy - ship->vy)/70 );
             chance -= ( abs(target->vz - ship->vz)/70 );
             chance = URANGE( 10 , chance , 90 );
	     }

	     else if ( asteroid != NULL && target == NULL )
	     {
             chance += asteroid->type*25;
	     if ( asteroid->stype == 1 )
		chance -= asteroid->stype*28;
	     else
		chance -= asteroid->stype*10;
             chance -= asteroid->speed/20;
             chance -= ( abs(asteroid->x - ship->vx)/70 );
             chance -= ( abs(asteroid->y - ship->vy)/70 );
             chance -= ( abs(asteroid->z - ship->vz)/70 );
             chance = URANGE( 10 , chance , 90 );

	     }
	     else
	     {
		send_to_char( "The target seems to have vanished!\n\r", ch );
		return;
	     }

             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             if ( number_percent( ) > chance )
             {  
		if ( target != NULL && asteroid == NULL )
		{
                sprintf( buf , "Lasers fire from %s at you but miss." , ship->name);  
                echo_to_cockpit( AT_ORANGE , target , buf );           
                sprintf( buf , "The ships lasers fire at %s but miss." , target->name);  
                echo_to_cockpit( AT_ORANGE , ship , buf );           
                learn_from_failure( ch, gsn_spacecombat ); 
    	        learn_from_failure( ch, gsn_spacecombat2 ); 
    	        learn_from_failure( ch, gsn_spacecombat3 ); 
    	        sprintf( buf, "Laserfire from %s barely misses %s." , ship->name , target->name );
                echo_to_system( AT_ORANGE , ship , buf , target );
		}

		else if ( asteroid != NULL && target == NULL )
		{
                sprintf( buf , "The ships lasers fire at %s but miss." , asteroid->name);  
                echo_to_cockpit( AT_ORANGE , ship , buf );           
                learn_from_failure( ch, gsn_spacecombat ); 
    	        learn_from_failure( ch, gsn_spacecombat2 ); 
    	        learn_from_failure( ch, gsn_spacecombat3 ); 
    	        sprintf( buf, "Laserfire from %s barely misses %s." , ship->name , asteroid->name );
                echo_to_system( AT_ORANGE , ship , buf , target );
		}

    	        return;	
             } 
	    if ( target != NULL && asteroid == NULL )
	    {
             sprintf( buf, "Laserfire from %s hits %s." , ship->name, target->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             sprintf( buf , "You are hit by lasers from %s!" , ship->name);  
             echo_to_cockpit( AT_BLOOD , target , buf );           
             sprintf( buf , "Your ships lasers hit %s!." , target->name);  
             echo_to_cockpit( AT_YELLOW , ship , buf );           
             learn_from_success( ch, gsn_spacecombat );
             learn_from_success( ch, gsn_spacecombat2 );
             learn_from_success( ch, gsn_spacecombat3 );
             echo_to_ship( AT_RED , target , "A small explosion vibrates through the ship." );           
             damage_ship_ch( target , 5 , 10 , ch );
            }

	     else if ( asteroid != NULL && target == NULL )
	     {
             sprintf( buf, "Laserfire from %s hits %s." , ship->name, asteroid->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             sprintf( buf , "Your ships lasers hit %s!." , asteroid->name);  
             echo_to_cockpit( AT_YELLOW , ship , buf );           
             learn_from_success( ch, gsn_spacecombat );
             learn_from_success( ch, gsn_spacecombat2 );
             learn_from_success( ch, gsn_spacecombat3 );
             damage_asteroid_ch( asteroid , 5 , 10 , ch );
	     }

             if ( autofly(target) && target->target0 != ship )
             {
                target->target0 = ship; 
                sprintf( buf , "You are being targetted by %s." , target->name);  
                echo_to_cockpit( AT_BLOOD , ship , buf );
             }
             
             return;
    	}
        
        if ( ch->in_room->vnum == ship->gunseat && !str_prefix( argument , "missile") )
    	{
    	     if (ship->missilestate == MISSILE_DAMAGED)
    	     {
    	        send_to_char("&RThe ships missile launchers are dammaged.\n\r",ch);
    	      	return;
    	     } 
             if (ship->missiles <= 0)
    	     {
    	     	send_to_char("&RYou have no missiles to fire!\n\r",ch);
    	        return;
    	     }
    	     if (ship->missilestate != MISSILE_READY )
    	     {
    	     	send_to_char("&RThe missiles are still reloading.\n\r",ch);
    	     	return;
    	     }
    	     if (ship->target0 == NULL )
    	     {
    	     	send_to_char("&RYou need to choose a target first.\n\r",ch);
    	     	return;
    	     }    	    
    	     target = ship->target0;
             if (ship->target0->starsystem != ship->starsystem)
    	     {
    	     	send_to_char("&RYour target seems to have left.\n\r",ch);
    	        ship->target0 = NULL; 
    	     	return;
    	     } 
             if ( abs(target->vx - ship->vx) >1000 ||
                  abs(target->vy - ship->vy) >1000 ||
                  abs(target->vz - ship->vz) >1000 )
             {
                send_to_char("&RThat ship is out of missile range.\n\r",ch);
    	     	return;
             } 
             if ( ship->class < 2 && !is_facing( ship, target ) )
             {
                send_to_char("&RMissiles can only fire in a forward. You'll need to turn your ship!\n\r",ch);
    	     	return;
             }      
             chance -= target->manuever/5;
             chance -= target->currspeed/20;
             chance += target->class*target->class*25;
             chance -= ( abs(target->vx - ship->vx)/100 );
             chance -= ( abs(target->vy - ship->vy)/100 );
             chance -= ( abs(target->vz - ship->vz)/100 );                          
             chance += ( 30 );
             chance = URANGE( 20 , chance , 80 );
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             if ( number_percent( ) > chance )
             {
                send_to_char( "&RYou fail to lock onto your target!", ch );
                ship->missilestate = MISSILE_RELOAD_2;
    	        return;	
             } 
             new_missile( ship , target , ch , CONCUSSION_MISSILE );
             ship->missiles-- ;
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             echo_to_cockpit( AT_YELLOW , ship , "Missiles launched.");
             sprintf( buf , "Incoming missile from %s." , ship->name);  
             echo_to_cockpit( AT_BLOOD , target , buf );
             sprintf( buf, "%s fires a missile towards %s." , ship->name, target->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             learn_from_success( ch, gsn_weaponsystems );
             if ( ship->class == CAPITAL_SHIP || ship->class == SHIP_PLATFORM )
                   ship->missilestate = MISSILE_RELOAD;
             else
                   ship->missilestate = MISSILE_FIRED;
             
             if ( autofly(target) && target->target0 != ship )
             {
                target->target0 = ship; 
                sprintf( buf , "You are being targetted by %s." , target->name);  
                echo_to_cockpit( AT_BLOOD , ship , buf );
             }
             
             return;
    	}
        if ( ch->in_room->vnum == ship->gunseat && !str_prefix( argument , "torpedo") )
    	{
    	     if (ship->missilestate == MISSILE_DAMAGED)
    	     {
    	        send_to_char("&RThe ships missile launchers are dammaged.\n\r",ch);
    	      	return;
    	     } 
             if (ship->torpedos <= 0)
    	     {
    	     	send_to_char("&RYou have no torpedos to fire!\n\r",ch);
    	        return;
    	     }
    	     if (ship->missilestate != MISSILE_READY )
    	     {
    	     	send_to_char("&RThe torpedos are still reloading.\n\r",ch);
    	     	return;
    	     }
    	     if (ship->target0 == NULL )
    	     {
    	     	send_to_char("&RYou need to choose a target first.\n\r",ch);
    	     	return;
    	     }    	    
    	     target = ship->target0;
             if (ship->target0->starsystem != ship->starsystem)
    	     {
    	     	send_to_char("&RYour target seems to have left.\n\r",ch);
    	        ship->target0 = NULL; 
    	     	return;
    	     } 
             if ( abs(target->vx - ship->vx) >1000 ||
                  abs(target->vy - ship->vy) >1000 ||
                  abs(target->vz - ship->vz) >1000 )
             {
                send_to_char("&RThat ship is out of torpedo range.\n\r",ch);
    	     	return;
             } 
             if ( ship->class < 2 && !is_facing( ship, target ) )
             {
                send_to_char("&RTorpedos can only fire in a forward direction. You'll need to turn your ship!\n\r",ch);
    	     	return;
             }      
             chance -= target->manuever/5;
             chance -= target->currspeed/20;
             chance += target->class*target->class*25;
             chance -= ( abs(target->vx - ship->vx)/100 );
             chance -= ( abs(target->vy - ship->vy)/100 );
             chance -= ( abs(target->vz - ship->vz)/100 );                          
             chance = URANGE( 20 , chance , 80 );
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             if ( number_percent( ) > chance )
             {
                send_to_char( "&RYou fail to lock onto your target!", ch );
                ship->missilestate = MISSILE_RELOAD_2;
    	        return;	
             } 
             new_missile( ship , target , ch , PROTON_TORPEDO );
             ship->torpedos-- ;
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             echo_to_cockpit( AT_YELLOW , ship , "Missiles launched.");
             sprintf( buf , "Incoming torpedo from %s." , ship->name);  
             echo_to_cockpit( AT_BLOOD , target , buf );
             sprintf( buf, "%s fires a torpedo towards %s." , ship->name, target->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             learn_from_success( ch, gsn_weaponsystems );
             if ( ship->class == CAPITAL_SHIP || ship->class == SHIP_PLATFORM )
                   ship->missilestate = MISSILE_RELOAD;
             else
                   ship->missilestate = MISSILE_FIRED;
             
             if ( autofly(target) && target->target0 != ship )
             {
                target->target0 = ship; 
                sprintf( buf , "You are being targetted by %s." , target->name);  
                echo_to_cockpit( AT_BLOOD , ship , buf );
             }
             
             return;
    	}
    	
        if ( ch->in_room->vnum == ship->gunseat && !str_prefix( argument , "rocket") )
    	{
    	     if (ship->missilestate == MISSILE_DAMAGED)
    	     {
    	        send_to_char("&RThe ships missile launchers are damaged.\n\r",ch);
    	      	return;
    	     } 
             if (ship->rockets <= 0)
    	     {
    	     	send_to_char("&RYou have no rockets to fire!\n\r",ch);
    	        return;
    	     }
    	     if (ship->missilestate != MISSILE_READY )
    	     {
    	     	send_to_char("&RThe missiles are still reloading.\n\r",ch);
    	     	return;
    	     }
    	     if (ship->target0 == NULL )
    	     {
    	     	send_to_char("&RYou need to choose a target first.\n\r",ch);
    	     	return;
    	     }    	    
    	     target = ship->target0;
             if (ship->target0->starsystem != ship->starsystem)
    	     {
    	     	send_to_char("&RYour target seems to have left.\n\r",ch);
    	        ship->target0 = NULL; 
    	     	return;
    	     } 
             if ( abs(target->vx - ship->vx) >800 ||
                  abs(target->vy - ship->vy) >800 ||
                  abs(target->vz - ship->vz) >800 )
             {
                send_to_char("&RThat ship is out of rocket range.\n\r",ch);
    	     	return;
             } 
             if ( ship->class < 2 && !is_facing( ship, target ) )
             {
                send_to_char("&RRockets can only fire forward. You'll need to turn your ship!\n\r",ch);
    	     	return;
             }      
             chance -= target->manuever/5;
             chance -= target->currspeed/20;
             chance += target->class*target->class*25;
             chance -= ( abs(target->vx - ship->vx)/100 );
             chance -= ( abs(target->vy - ship->vy)/100 );
             chance -= ( abs(target->vz - ship->vz)/100 );                          
             chance -= 30 ;
             chance = URANGE( 20 , chance , 80 );
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             if ( number_percent( ) > chance )
             {
                send_to_char( "&RYou fail to lock onto your target!", ch );
                ship->missilestate = MISSILE_RELOAD_2;
    	        return;	
             } 
             new_missile( ship , target , ch , HEAVY_ROCKET );
             ship->rockets-- ;
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             echo_to_cockpit( AT_YELLOW , ship , "Rocket launched.");
             sprintf( buf , "Incoming rocket from %s." , ship->name);  
             echo_to_cockpit( AT_BLOOD , target , buf );
             sprintf( buf, "%s fires a heavy rocket towards %s." , ship->name, target->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             learn_from_success( ch, gsn_weaponsystems );
             if ( ship->class == CAPITAL_SHIP || ship->class == SHIP_PLATFORM )
                   ship->missilestate = MISSILE_RELOAD;
             else
                   ship->missilestate = MISSILE_FIRED;
             
             if ( autofly(target) && target->target0 != ship )
             {
                target->target0 = ship; 
                sprintf( buf , "You are being targetted by %s." , target->name);  
                echo_to_cockpit( AT_BLOOD , ship , buf );
             }
             
             return;
    	}
        
        if ( ch->in_room->vnum == ship->turret1 && !str_prefix( argument , "lasers") )
    	{
    	     if (ship->statet1 == LASER_DAMAGED)
    	     {
    	        send_to_char("&RThe ships turret is damaged.\n\r",ch);
    	      	return;
    	     } 
             if (ship->statet1 > ship->class )
    	     {
    	     	send_to_char("&RThe turbolaser is recharging.\n\r",ch);
    	     	return;
    	     }
    	     if (ship->target1 == NULL )
    	     {
    	     	send_to_char("&RYou need to choose a target first.\n\r",ch);
    	     	return;
    	     }    	    
    	     target = ship->target1;
             if (ship->target1->starsystem != ship->starsystem)
    	     {
    	     	send_to_char("&RYour target seems to have left.\n\r",ch);
    	        ship->target1 = NULL; 
    	     	return;
    	     } 
             if ( abs(target->vx - ship->vx) >1000 ||
                  abs(target->vy - ship->vy) >1000 ||
                  abs(target->vz - ship->vz) >1000 )
             {
                send_to_char("&RThat ship is out of laser range.\n\r",ch);
    	     	return;
             } 
             ship->statet1++;
             chance -= target->manuever/10;
             chance += target->class*25;
             chance -= target->currspeed/20;
             chance -= ( abs(target->vx - ship->vx)/70 );
             chance -= ( abs(target->vy - ship->vy)/70 );
             chance -= ( abs(target->vz - ship->vz)/70 );
             chance = URANGE( 10 , chance , 90 );
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             if ( number_percent( ) > chance )
             {  
                sprintf( buf , "Turbolasers fire from %s at you but miss." , ship->name);  
                echo_to_cockpit( AT_ORANGE , target , buf );           
                sprintf( buf , "Turbolasers fire from the ships turret at %s but miss." , target->name);  
                echo_to_cockpit( AT_ORANGE , ship , buf );           
                sprintf( buf, "%s fires at %s but misses." , ship->name, target->name );
                echo_to_system( AT_ORANGE , ship , buf , target );
                learn_from_failure( ch, gsn_spacecombat ); 
    	        learn_from_failure( ch, gsn_spacecombat2 ); 
    	        learn_from_failure( ch, gsn_spacecombat3 ); 
    	        return;	
             } 
             sprintf( buf, "Turboasers fire from %s, hitting %s." , ship->name, target->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             sprintf( buf , "You are hit by turbolasers from %s!" , ship->name);  
             echo_to_cockpit( AT_BLOOD , target , buf );           
             sprintf( buf , "Turbolasers fire from the turret, hitting %s!." , target->name);  
             echo_to_cockpit( AT_YELLOW , ship , buf );           
             learn_from_success( ch, gsn_spacecombat );
             learn_from_success( ch, gsn_spacecombat2 );
             learn_from_success( ch, gsn_spacecombat3 );
             echo_to_ship( AT_RED , target , "A small explosion vibrates through the ship." );           
             damage_ship_ch( target , 10 , 25 , ch );
             
             if ( autofly(target) && target->target0 != ship )
             {
                target->target0 = ship; 
                sprintf( buf , "You are being targetted by %s." , target->name);  
                echo_to_cockpit( AT_BLOOD , ship , buf );
             }
             
             return;
    	}
        
        if ( ch->in_room->vnum == ship->turret2 && !str_prefix( argument , "lasers") )
    	{
    	     if (ship->statet2 == LASER_DAMAGED)
    	     {
    	        send_to_char("&RThe ships turret is damaged.\n\r",ch);
    	      	return;
    	     } 
             if (ship->statet2 > ship->class )
    	     {
    	     	send_to_char("&RThe turbolaser is still recharging.\n\r",ch);
    	     	return;
    	     }
    	     if (ship->target2 == NULL )
    	     {
    	     	send_to_char("&RYou need to choose a target first.\n\r",ch);
    	     	return;
    	     }    	    
    	     target = ship->target2;
             if (ship->target2->starsystem != ship->starsystem)
    	     {
    	     	send_to_char("&RYour target seems to have left.\n\r",ch);
    	        ship->target2 = NULL; 
    	     	return;
    	     } 
    	     if ( abs(target->vx - ship->vx) >1000 ||
                  abs(target->vy - ship->vy) >1000 ||
                  abs(target->vz - ship->vz) >1000 )
             {
                send_to_char("&RThat ship is out of laser range.\n\r",ch);
    	     	return;
             } 

             ship->statet2++;
             chance -= target->manuever/10;
             chance += target->class*25;
             chance -= target->currspeed/20;
             chance -= ( abs(target->vx - ship->vx)/70 );
             chance -= ( abs(target->vy - ship->vy)/70 );
             chance -= ( abs(target->vz - ship->vz)/70 );
             chance = URANGE( 10 , chance , 90 );
             act( AT_PLAIN, "$n presses the fire button.", ch,
                  NULL, argument , TO_ROOM );
             if ( number_percent( ) > chance )
             {  
                sprintf( buf, "Turbolasers fire from %s barely missing %s." , ship->name, target->name );
                echo_to_system( AT_ORANGE , ship , buf , target );
                sprintf( buf , "Turbolasers fire from %s at you but miss." , ship->name);  
                echo_to_cockpit( AT_ORANGE , target , buf );           
                sprintf( buf , "Turbolasers fire from the turret missing %s." , target->name);  
                echo_to_cockpit( AT_ORANGE , ship , buf );           
                learn_from_failure( ch, gsn_spacecombat ); 
    	        learn_from_failure( ch, gsn_spacecombat2 ); 
    	        learn_from_failure( ch, gsn_spacecombat3 ); 
    	        return;	
             } 
             sprintf( buf, "Turbolasers fire from %s, hitting %s." , ship->name, target->name );
             echo_to_system( AT_ORANGE , ship , buf , target );
             sprintf( buf , "You are hit by turbolasers from %s!" , ship->name);  
             echo_to_cockpit( AT_BLOOD , target , buf );           
             sprintf( buf , "turbolasers fire from the turret hitting %s!." , target->name);  
             echo_to_cockpit( AT_YELLOW , ship , buf );           
             learn_from_success( ch, gsn_spacecombat );
             learn_from_success( ch, gsn_spacecombat2 );
             learn_from_success( ch, gsn_spacecombat3 );
             echo_to_ship( AT_RED , target , "A small explosion vibrates through the ship." );           
             damage_ship_ch( target , 10 , 25 , ch);
             
             if ( autofly(target) && target->target0 != ship )
             {
                target->target0 = ship; 
                sprintf( buf , "You are being targetted by %s." , target->name);  
                echo_to_cockpit( AT_BLOOD , ship , buf );
             }
             
             return;
    	}
        
        send_to_char( "&RYou can't fire that!\n\r" , ch);
    	
}
-----------------------
Whew! Alright, back to good instructions!

Find do_radar and add     ASTEROID_DATA *asteroid; under the MISSILE_DATA declaration.
-----------------------
Find in that same function:
     for ( target = ship->starsystem->first_ship; target; target = target->next_in_starsystem )

Add -ABOVE- that:
                   for ( asteroid = ship->starsystem->first_asteroid; asteroid; asteroid = asteroid->next_in_system )
                   {
                        ch_printf( ch, "%s  %.0f %.0f %.0f\n\r",
                                asteroid->name,
                                asteroid->x,
                                asteroid->y,
                                asteroid->z);
                   }

=======================================================
End of Part 2: Instructions for adding findship command
=======================================================

Compile
=======
Make clean, then a Make (recompile).

Ending Notes
============
Go through asteroids.c and edit any references to home_system named "Terra" to what ever a name of a star system
is in your game. This will be the "default" starsystem for -ALL- asteroids. Of course you can change it using
setasteroid.

I highly highly suggest you go through the code and change anything thats mud specific. Such as if there was
a fatal error I probably put to e-mail admin@ew.xidus.net when that should be the e-mail of your mud. This may or
may not be the case, I don't really remember or care enough to search for it. I do suggest you look over the code so
you can see what you are dealing with and find possible ways to expand. ::cough:: flag system ::cough cough:: :P

I hope you don't have the pedantic flag on because you'll be raising hell. If you do have it and decide to fix its
stuff then send me a copy of the working stuff and I'll use it instead :)

When you logon the mud you need to use cedit to put your new commands into action. This can be done like this:

cedit makeasteroid create do_makeasteroid
cedit setasteroid create do_setasteroid
cedit resetasteroid create do_resetasteroid
cedit copyasteroid create do_copyasteroid
cedit showasteroid create do_showasteroid

cedit save

Please note you need to adjust your command levels accordingly using cedit <command> level <new level>.

Making your first asteroid:
Lets say you want an asteroid named Bob. He is going to be a small ice asteroid. Thus, you do this...

command    filename   asteroids name
    |         |        |
    V         V        V
makeasteroid bob.ast Bob the Asteroid

setasteroid bob type small
setasteroid bob stype ice

Now, I want this little guy to have default hp and experience...so, I use resetasteroid...

resetasteroid bob 1 1 -1 y

This gives bob hp according to the generate_hp function and a default experience of his maxhp * 5. It also saves Bob.

Note: The maxhp * 5 generally tends to be a lot of experience, but then again, it takes a long time to kill most asteroids
with lasers...lol

To delete asteroids
--------------------
When the mud is down or is going to be rebooted/copyovered just remove them from asteroid.lst in the asteroids folder and
delete their files.

Contact Information:
===================
Please send comments, suggestions, bugs, etc. to my e-mail. Problems with installation? Hit up my forums at
http://ew.xidus.net/modules.php?name=Forums or post on the forums at gammon.com.au.

Thanks, I hope you enjoy this code,
Odis, Owner, Coder, and Head Immortal of Gundam Wing: The Awakening
http://ew.xidus.net
admin@ew.xidus.net